package npc

import chisel3._
import chisel3.util._

trait Instr {
  //                                 imm[31:12]    rd  opcode
  def LUI___ = BitPat("b??????? ????? ????? ??? ????? 0110111")
  def AUIPC_ = BitPat("b??????? ????? ????? ??? ????? 0010111")
  //                      imm[20|10:1|11|19:12]    rd  opcode
  def JAL___ = BitPat("b??????? ????? ????? ??? ????? 1101111")
  //                        imm[11:0]   rs1 funct3 rd  opcode
  def JALR__ = BitPat("b??????? ????? ????? 000 ????? 1100111")
  //               imm[12|10:5]   rs2   rs1 funct3 imm[4:1|11] opcode
  def BEQ___ = BitPat("b??????? ????? ????? 000 ????? 1100011")
  def BNE___ = BitPat("b??????? ????? ????? 001 ????? 1100011")
  def BLT___ = BitPat("b??????? ????? ????? 100 ????? 1100011")
  def BGE___ = BitPat("b??????? ????? ????? 101 ????? 1100011")
  def BLTU__ = BitPat("b??????? ????? ????? 110 ????? 1100011")
  def BGEU__ = BitPat("b??????? ????? ????? 111 ????? 1100011")
  //                        imm[11:0]   rs1 funct3 rd  opcode
  def LB____ = BitPat("b??????? ????? ????? 000 ????? 0000011")
  def LH____ = BitPat("b??????? ????? ????? 001 ????? 0000011")
  def LW____ = BitPat("b??????? ????? ????? 010 ????? 0000011")
  def LBU___ = BitPat("b??????? ????? ????? 100 ????? 0000011")
  def LHU___ = BitPat("b??????? ????? ????? 101 ????? 0000011")
  //                  imm[11:5]   rs2   rs1 funct3 imm[4:0] opcode
  def SB____ = BitPat("b??????? ????? ????? 000 ????? 0100011")
  def SH____ = BitPat("b??????? ????? ????? 001 ????? 0100011")
  def SW____ = BitPat("b??????? ????? ????? 010 ????? 0100011")
  //                        imm[11:0]   rs1 funct3 rd  opcode
  def ADDI__ = BitPat("b??????? ????? ????? 000 ????? 0010011")
  def SLTI__ = BitPat("b??????? ????? ????? 010 ????? 0010011")
  def SLTIU_ = BitPat("b??????? ????? ????? 011 ????? 0010011")
  def XORI__ = BitPat("b??????? ????? ????? 100 ????? 0010011")
  def ORI___ = BitPat("b??????? ????? ????? 110 ????? 0010011")
  def ANDI__ = BitPat("b??????? ????? ????? 111 ????? 0010011")
  //                        imm shamt   rs1 funct3 rd  opcode
  def SLLI__ = BitPat("b0000000 ????? ????? 001 ????? 0010011")
  def SRLI__ = BitPat("b0000000 ????? ????? 101 ????? 0010011")
  def SRAI__ = BitPat("b0100000 ????? ????? 101 ????? 0010011")
  //                        imm   rs2   rs1 funct3 rd  opcode
  def ADD___ = BitPat("b0000000 ????? ????? 000 ????? 0110011")
  def SUB___ = BitPat("b0100000 ????? ????? 000 ????? 0110011")
  def SLL___ = BitPat("b0000000 ????? ????? 001 ????? 0110011")
  def SLT___ = BitPat("b0000000 ????? ????? 010 ????? 0110011")
  def SLTU__ = BitPat("b0000000 ????? ????? 011 ????? 0110011")
  def XOR___ = BitPat("b0000000 ????? ????? 100 ????? 0110011")
  def SRL___ = BitPat("b0000000 ????? ????? 101 ????? 0110011")
  def SRA___ = BitPat("b0100000 ????? ????? 101 ????? 0110011")
  def OR____ = BitPat("b0000000 ????? ????? 110 ????? 0110011")
  def AND___ = BitPat("b0000000 ????? ????? 111 ????? 0110011")

  def ECALL_ = BitPat("b0000000 00000 00000 000 00000 1110011")
  def EBREAK = BitPat("b0000000 00001 00000 000 00000 1110011")

  def FENCE____ = BitPat("b0000??? ????? 00000 000 00000 0001111")
  def FENCE_TSO = BitPat("b1000001 10011 00000 000 00000 0011111")
  // Zifencei               imm[11:0]   rs1 func3  rd  opcode
  def FENCE_I__ = BitPat("b??????? ????? ????? 001 ????? 0001111")
  // Zifencetime
  def FENCE_TIM = BitPat("b0000000 00000 00000 010 00000 0001111")

  def SFENCE_VM = BitPat("b0001001 ????? ????? 000 00000 1110011")

  // RV32/RV64 Zicsr              csr   rs1 func3  rd  opcode
  def CSRRW_ = BitPat("b??????? ????? ????? 001 ????? 1110011")
  def CSRRS_ = BitPat("b??????? ????? ????? 010 ????? 1110011")
  def CSRRC_ = BitPat("b??????? ????? ????? 011 ????? 1110011")
  // RV32/RV64 Zicsr i            csr  uimm func3  rd  opcode
  def CSRRWI = BitPat("b??????? ????? ????? 101 ????? 1110011")
  def CSRRSI = BitPat("b??????? ????? ????? 110 ????? 1110011")
  def CSRRCI = BitPat("b??????? ????? ????? 111 ????? 1110011")
  // RV32M                  imm   rs2   rs1 funct3 rd  opcode
  def MUL___ = BitPat("b0000001 ????? ????? 000 ????? 0110011")
  def MULH__ = BitPat("b0000001 ????? ????? 001 ????? 0110011")
  def MULHSU = BitPat("b0000001 ????? ????? 010 ????? 0110011")
  def MULHU_ = BitPat("b0000001 ????? ????? 011 ????? 0110011")
  def DIV___ = BitPat("b0000001 ????? ????? 100 ????? 0110011")
  def DIVU__ = BitPat("b0000001 ????? ????? 101 ????? 0110011")
  def REM___ = BitPat("b0000001 ????? ????? 110 ????? 0110011")
  def REMU__ = BitPat("b0000001 ????? ????? 111 ????? 0110011")

  // RV32A                      ar  rs2   rs1  f3    rd   opcode
  def LR_W__    = BitPat("b00010?? 00000 ????? 010 ????? 0101111")
  def SC_W__    = BitPat("b00011?? ????? ????? 010 ????? 0101111")
  def AMOSWAP_W = BitPat("b00001?? ????? ????? 010 ????? 0101111")
  def AMOADD_W_ = BitPat("b00000?? ????? ????? 010 ????? 0101111")
  def AMOXOR_W_ = BitPat("b00100?? ????? ????? 010 ????? 0101111")
  def AMOAND_W_ = BitPat("b01100?? ????? ????? 010 ????? 0101111")
  def AMOOR_W__ = BitPat("b01000?? ????? ????? 010 ????? 0101111")
  def AMOMIN_W_ = BitPat("b10000?? ????? ????? 010 ????? 0101111")
  def AMOMAX_W_ = BitPat("b10100?? ????? ????? 010 ????? 0101111")
  def AMOMINU_W = BitPat("b11000?? ????? ????? 010 ????? 0101111")
  def AMOMAXU_W = BitPat("b11100?? ????? ????? 010 ????? 0101111")

  // Trap-Return          func7   rs2   rs1 func3  rd  opcode
  def MRET__ = BitPat("b0011000 00010 00000 000 00000 1110011")
  def SRET__ = BitPat("b0001000 00010 00000 000 00000 1110011")

  def WFI___ = BitPat("b0001000 00101 00000 000 00000 1110011")

  // RVC compressed instructions
  // Instruction listing for RVC, Quadrant 0
  def C_INV_     = BitPat("b000 00000000 000 00")
  def C_ADDI4SPN = BitPat("b000 ???????? ??? 00")
  def C_FLD_     = BitPat("b001 ???????? ??? 00")
  def C_LQ__     = BitPat("b001 ???????? ??? 00")
  def C_LW__     = BitPat("b010 ???????? ??? 00")
  def C_FLW_     = BitPat("b011 ???????? ??? 00")
  def C_LD__     = BitPat("b011 ???????? ??? 00")
  def C_REV_     = BitPat("b100 ???????? ??? 00")
  def C_FSD_     = BitPat("b101 ???????? ??? 00")
  def C_SQ__     = BitPat("b101 ???????? ??? 00")
  def C_SW__     = BitPat("b110 ???????? ??? 00")
  def C_FSW_     = BitPat("b111 ???????? ??? 00")
  def C_SD__     = BitPat("b111 ???????? ??? 00")
  // Instruction listing for RVC, Quadrant 1
  def C_NOP_     = BitPat("b000 ?00000?? ??? 01")
  def C_ADDI     = BitPat("b000 ???????? ??? 01")
  def C_JAL_     = BitPat("b001 ???????? ??? 01")
  def C_ADDIW    = BitPat("b001 ???????? ??? 01")
  def C_LI__     = BitPat("b010 ???????? ??? 01")
  def C_ADDI16sp = BitPat("b011 ?00010?? ??? 01")
  def C_LUI_     = BitPat("b011 ???????? ??? 01")
  def C_SRLI     = BitPat("b100 ?00????? ??? 01")
  def C_SRLI64   = BitPat("b100 000???00 000 01")
  def C_SRAI     = BitPat("b100 ?01????? ??? 01")
  def C_SRAI64   = BitPat("b100 001???00 000 01")
  def C_ANDI     = BitPat("b100 ?10????? ??? 01")
  def C_SUB_     = BitPat("b100 011???00 ??? 01")
  def C_XOR_     = BitPat("b100 011???01 ??? 01")
  def C_OR__     = BitPat("b100 011???10 ??? 01")
  def C_AND_     = BitPat("b100 011???11 ??? 01")
  def C_SUBW     = BitPat("b100 111???00 ??? 01")
  def C_ADDW     = BitPat("b100 111???01 ??? 01")
  def C_REV0     = BitPat("b100 111???10 ??? 01")
  def C_REV1     = BitPat("b100 111???11 ??? 01")
  def C_J___     = BitPat("b101 ???????? ??? 01")
  def C_BEQZ     = BitPat("b110 ???????? ??? 01")
  def C_BNEZ     = BitPat("b111 ???????? ??? 01")
  // Instruction listing for RVC, Quadrant 2
  def C_SLLI     = BitPat("b000 ???????? ??? 10")
  def C_SLLI64   = BitPat("b000 0??????? 000 10")
  def C_FLDSP    = BitPat("b001 ???????? ??? 10")
  def C_LQSP     = BitPat("b001 ???????? ??? 10")
  def C_LWSP     = BitPat("b010 ???????? ??? 10")
  def C_FLWSP    = BitPat("b011 ???????? ??? 10")
  def C_LDSP     = BitPat("b011 ???????? ??? 10")
  def C_JR__     = BitPat("b100 0?????00 000 10")
  def C_MV__     = BitPat("b100 0??????? ??? 10")
  def C_EBREAK   = BitPat("b100 10000000 000 10")
  def C_JALR     = BitPat("b100 1?????00 000 10")
  def C_ADD_     = BitPat("b100 1??????? ??? 10")
  def C_FSDSP    = BitPat("b101 ???????? ??? 10")
  def C_SQSP     = BitPat("b101 ???????? ??? 10")
  def C_SWSP     = BitPat("b110 ???????? ??? 10")
  def C_FSWSP    = BitPat("b111 ???????? ??? 10")
  def C_SDSP     = BitPat("b111 ???????? ??? 10")
}
